package sy4_Creational_Pattern.builder.wu2;

import lombok.Data;

/**
 * Builder：为创建一个产品对象的各个部件指定抽象接口。
 * ConcreteBuilder：实现Builder的接口以构造和装配该产品的各个部件，
 *     定义并明确它所创建的表示，并提供一个检索产品的接口。
 * Director：聚合Builder，构造一个使用Builder接口的对象。
 * Product：表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程，
 *     包含定义组成部件的类，包括将这些部件装配成最终产品的接口。
 *
 * 适用情形：
 * 1、创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式
 * 2、构造过程必须允许被构造的对象有不同的表示
 *
 * 注意：
 * 1、Builder定义产品各部件的建造方法，Director定义产品的构建方式。
 * 2、系统中，如果只需要一个具体建造者，则可以省略掉抽象建造者。
 */
public class Client {
    public static void main(String[] args) {
        PersonDirector director = new PersonDirector();
        director.setBuilder(new ManBuilder());
        Person person = director.constructPerson();
        System.out.println(person);
    }
}

//Builder
interface PersonBuilder {
    void buildHead();
    void buildBody();
    void buildFoot();
    Person buildPerson();
}

//ManBuilder作为 ConcreteBuilder，还可以创建 WomanBuilder
class ManBuilder implements PersonBuilder {
    Person person;

    public ManBuilder() {
        person = new Person();
    }

    public void buildHead() {
        person.setHead("男人的头");
    }

    public void buildBody() {
        person.setBody("男人的身体");
    }
    public void buildFoot() {
        person.setFoot("男人的脚");
    }

    public Person buildPerson() {
        return person;
    }
}

//Director
class PersonDirector {
    private PersonBuilder builder;

    public void setBuilder(PersonBuilder builder) {
        this.builder = builder;
    }

    public Person constructPerson() {
        builder.buildHead();
        builder.buildBody();
        builder.buildFoot();
        return builder.buildPerson();  //方法返回值类型为 Person
    }
}

//Product
@Data
class Person {
    private String head;
    private String body;
    private String foot;
}


